/*
 *  Unit test.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

#define PARSE_INPUT_FILE "test.in"
#define PARSE_OUTPUT_FILE "test.out"
#define PARSE_FILE "./log_parser_test"

#define BUFF_SIZE 2000
#define KEY_WORD "IPcontext OSLFW: "

/* Pointer to the files used by the tests. */
static FILE* test_in = NULL;
static FILE* test_out = NULL;
static FILE* status = NULL;

/* Test of empty input file.
 * Run the program without writing to input file.
 */
int testEmptyInput(void)
{
	int ret_val = 0;
	int pid, st, w;
	char* argv[] = {"", PARSE_OUTPUT_FILE, (char *)0};
	char str[BUFF_SIZE];

	/* Create empty input file */
	if (NULL == (test_in = fopen(PARSE_INPUT_FILE, "w")))
		return -1;

	if (0 != fclose(test_in))
		return -1;

	if (0 == (pid = fork()))
	{
		/* Process 1 is going to execute log_parse_test */
		ret_val = execv(PARSE_FILE, argv);
		return ret_val;
	}
	else
	{
		/* Process 2 is waiting and checks the resuls */
		do
		{
			w = waitpid(pid, &st, 0);
		} while(!WIFEXITED(st));

		/* Read the output file and compare the expected output to actual */
		if (NULL == (test_out = fopen(PARSE_OUTPUT_FILE, "r")))
			return -1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were started:"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were accepted."))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were denied."))
			return 1;

		if (0 != fclose(test_out))
			return -1;

		return ret_val;
	}
}

/* Test of input file with reports to user.
 * Write toinput file and run the program.
 */
int testFullInput(void)
{
	int ret_val = 0;
	int pid, st, w;
	char* argv[] = {"", PARSE_OUTPUT_FILE, (char *)0};
	char str[BUFF_SIZE];

	/* Fill the input file */
	if (NULL == (test_in = fopen(PARSE_INPUT_FILE, "w")))
		return -1;

	sprintf(str, "%s 1 accepted\n", KEY_WORD);
	fputs(str, test_in);
	sprintf(str, "%s 2 denied\n", KEY_WORD);
	fputs(str, test_in);
	sprintf(str, "%s 3 accepted\n", KEY_WORD);
	fputs(str, test_in);

	/* Work with input file is finished */
	if (0 != fclose(test_in))
		return -1;

	if (0 == (pid = fork()))
	{
		/* Process 1 is going to execute log_parse_test */
		ret_val = execv(PARSE_FILE, argv);
		return ret_val;
	}
	else
	{
		/* Process 2 is waiting and checks the resuls */
		do
		{
			w = waitpid(pid, &st, 0);
		} while(!WIFEXITED(st));

		/* Read the output file and compare the expected output to actual */
		if (NULL == (test_out = fopen(PARSE_OUTPUT_FILE, "r")))
			return -1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "1 accepted"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "2 denied"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "3 accepted"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "3 sessions were started:"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "2 sessions were accepted."))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "1 sessions were denied."))
			return 1;

		if (0 != fclose(test_out))
			return -1;

		return ret_val;
	}
}

/* Test of input file with trash.
 * Write to input file and run the program.
 */
int testTrashInput(void)
{
	int ret_val = 0;
	int pid, st, w;
	char* argv[] = {"", PARSE_OUTPUT_FILE, (char *)0};
	char str[BUFF_SIZE];

	/* Fill the input file */
	if (NULL == (test_in = fopen(PARSE_INPUT_FILE, "w")))
		return -1;

	sprintf(str, "1 accepted\n");
	fputs(str, test_in);
	sprintf(str, "2 denied\n");
	fputs(str, test_in);
	sprintf(str, "3 accepted\n");
	fputs(str, test_in);

	/* Work with input file is finished */
	if (0 != fclose(test_in))
		return -1;

	if (0 == (pid = fork()))
	{
		/* Process 1 is going to execute log_parse_test */
		ret_val = execv(PARSE_FILE, argv);
		return ret_val;
	}
	else
	{
		/* Process 2 is waiting and checks the resuls */
		do
		{
			w = waitpid(pid, &st, 0);
		} while(!WIFEXITED(st));

		/* Read the output file and compare the expected output to actual */
		if (NULL == (test_out = fopen(PARSE_OUTPUT_FILE, "r")))
			return -1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were started:"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were accepted."))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "0 sessions were denied."))
			return 1;

		if (0 != fclose(test_out))
			return -1;

		return ret_val;
	}
}


/* Test of input file with trash and reports to user.
 * Write to input file and run the program.
 */
int testMixedInput(void)
{
	int ret_val = 0;
	int pid, st, w;
	char* argv[] = {"", PARSE_OUTPUT_FILE, (char *)0};
	char str[BUFF_SIZE];

	/* Fill the input file */
	if (NULL == (test_in = fopen(PARSE_INPUT_FILE, "w")))
		return -1;

	sprintf(str, "1 accepted\n");
	fputs(str, test_in);
	sprintf(str, "%s 2 denied\n", KEY_WORD);
	fputs(str, test_in);
	sprintf(str, "%s 3 accepted\n", KEY_WORD);
	fputs(str, test_in);

	/* Work with input file is finished */
	if (0 != fclose(test_in))
		return -1;

	if (0 == (pid = fork()))
	{
		/* Process 1 is going to execute log_parse_test */
		ret_val = execv(PARSE_FILE, argv);
		return ret_val;
	}
	else
	{
		/* Process 2 is waiting and checks the resuls */
		do
		{
			w = waitpid(pid, &st, 0);
		} while(!WIFEXITED(st));

		/* Read the output file and compare the expected output to actual */
		if (NULL == (test_out = fopen(PARSE_OUTPUT_FILE, "r")))
			return -1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "2 denied"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "3 accepted"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "2 sessions were started:"))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "1 sessions were accepted."))
			return 1;

		fgets(str, BUFF_SIZE, test_out);
		if(!strstr(str, "1 sessions were denied."))
			return 1;

		if (0 != fclose(test_out))
			return -1;

		return ret_val;
	}
}

/* The main() function for setting up and running the tests.
 */
int main()
{
	if(!testEmptyInput())
	{
		printf("Empty input file test successed\n");			
	}
	else
	{	
		printf("Empty input file problem\n");
	}

	if(!testFullInput())
	{
		printf("User reports input file test successed\n");			
	}
	else
	{	
		printf("User reports input file test problem\n");
	}

	if(!testTrashInput())
	{
		printf("Trash input file test successed\n");			
	}
	else
	{	
		printf("Trash input file test problem\n");
	}

	if(!testMixedInput())
	{
		printf("Mixed input file test successed\n");			
	}
	else
	{	
		printf("Mixed input file test problem\n");
	}
	return 0;
}
